#ifndef SOLVER_H
#define SOLVER_H

#include "fcsp.h"

namespace fcsp {
class Solver {
 public:
  Solver() { }

  // implement Fuzzy AC2001. partial=true selelect partial arc-consistency
  bool FuzzyAC2001(FCSP *csp, bool partial);

 private:
  // this is the struct used for a single support
  typedef struct Support {
    int value; // value of the support (a value of a domain of a variable)
    double pref; // preference of the support
    bool valid; // validity of the support

    Support(): value(-1), pref(0.0), valid(false) { }
  } Support;

  // data
  std::map< int, std::map< int, std::map<int, Support> > > supports_;

  // methods
  // find (force) supports for variable x in respect with constraint (x,y)
  bool FindSupports(Variable *x, Variable *y, FCSP *csp, bool partial);
  std::pair<bool, bool> PruneVar(Variable *x); // remove invalid values from domain of x
  Support GetSupport(int x_id, int x_value, int y_id); // retrieve a support S(x, x_val, y)
  // retrieve the maximum preference support for value_x with respect of constraint
  Support GetMaxPrefSupport(BinaryConstraint &constraint, int value_x);

  // comparator for Variable pointer using Variable's unique id
  struct VarPtrComp {
    bool operator() (const Variable *lhs, const Variable *rhs) const {
      return lhs->id() < rhs->id();
    }
  };
}; // class solver
} // namespace fcsp
#endif // SOLVER_H
